#include <string.h>

#include "tklog.h"
#include "tkerror.h"
#include "tkproto.h"
#include "tknetbusi.h"
#include "message.dsc.h"

void init_member_list(memberlist *mlist, int cmd_type) 
{
	memset(mlist, 0x00, sizeof(memberlist));
	mlist->cmd = cmd_type;
	mlist->_nodes_size = 250;
	mlist->_nodes_count = 0;
}

int add_member(memberlist *mlist, struct member *m)
{
	if (mlist->_nodes_size == mlist->_nodes_count)	
		return TK_TOOMUCH_MEMBER;
	
	memcpy(&mlist->nodes[mlist->_nodes_size - 1].node, m, sizeof(struct member));

	mlist->_nodes_size++;

	return 0;
}

struct member* get_last_member(memberlist *mlist)
{
	if (mlist->_nodes_size == 0)
		return NULL;

	return &mlist->nodes[mlist->_nodes_size - 1].node;
}

int query_member_byname(memberlist *mlist, struct member *m)
{
	int i;

	for (i = 0; i < mlist->_nodes_size; i++) {
		if (strcmp(mlist->nodes[i].node.clientname, m->clientname) == 0) {
			m->clientid = mlist->nodes[i].node.clientid;
			strcpy(m->clientname, mlist->nodes[i].node.clientname);
			strcpy(m->ip, mlist->nodes[i].node.ip);

			return TK_NOTFOUND;
		}
	}

	return 0;
}

int query_member_byid(memberlist *mlist, struct member *m)
{
        int i;

        for (i = 0; i < mlist->_nodes_size; i++) {
                if (mlist->nodes[i].node.clientid == m->clientid) {
                        strcpy(m->clientname, mlist->nodes[i].node.clientname);
                        strcpy(m->ip, mlist->nodes[i].node.ip);
			
			return 0;
                }
        }               
        
	return TK_NOTFOUND;
}

int query_member_byip(memberlist *mlist, struct member *m)
{
        int i;

        for (i = 0; i < mlist->_nodes_size; i++) {
                if (strcmp(mlist->nodes[i].node.ip, m->ip) == 0) {
			m->clientid = mlist->nodes[mlist->_nodes_size].node.clientid;
                        strcpy(m->clientname, mlist->nodes[mlist->_nodes_size].node.clientname);

                        return 0;
                }
        }

	return TK_NOTFOUND;
}

int del_member_byname(memberlist *mlist, struct member *m)
{
	int i;
	int found = 0;

        for (i = 0; i < mlist->_nodes_size; i++) {
                if (found == 0 && strcmp(mlist->nodes[i].node.clientname, m->clientname) == 0) {
			found = 1;
		}
		else if (found == 1) {
			memcpy(&mlist->nodes[i - 1].node, &mlist->nodes[i].node, sizeof(mlist->nodes[i].node));
		}
        }

	if (found == 1) {
		mlist->_nodes_size--;
		return 0;
	}
	else {
		return TK_NOTFOUND;
	}
}

int get_member_index(memberlist *mlist, struct member *m)
{
	unsigned long member_len = sizeof(struct member);

	if (m == NULL) 
		return -1;
	
	unsigned long diff = (unsigned long)m - (unsigned long)mlist->nodes;
	if (diff % member_len != 0)
		return -1;

	return (int)diff / member_len;	
}

inline void init_tk_message_header(struct tk_message *tk_msg, int len, int msg_type)
{
	tk_msg->header_len = HEADERLEN;
	sprintf(tk_msg->header, "%4d%4d", len, msg_type);
	tk_msg->header[HEADERLEN] = '\0';
}

int build_tk_message_with_memberlist(struct tk_message *tk_msg, memberlist *mlist)
{
	int r, len;

        memset(tk_msg, 0x00, sizeof(struct tk_message));
        len = MAXMESSAGELEN;
	
        r = DSCSERIALIZE_JSON_memberlist(mlist, "GBK", tk_msg->body, &len);
	if (r) 
		return r;
	else {
		init_tk_message_header(tk_msg, len, MSG_TYPE_MEMBER_LIST);
		tk_msg->body_len = len;
		tk_msg->body_tmp_len = len;

                return 0;
	}
}

int build_tk_message_with_clientinfo(struct tk_message *tk_msg, clientinfo *client)
{
	int r, len;
	
	memset(tk_msg, 0x00, sizeof(struct tk_message));
	len = MAXMESSAGELEN;

	r = DSCSERIALIZE_JSON_clientinfo(client, "GBK", tk_msg->body, &len);
	if (r) {
		return r;
	}
	else {
		init_tk_message_header(tk_msg, len, MSG_TYPE_CLIENT_INFO);
		tk_msg->body_len = len;
		tk_msg->body_tmp_len = len;

		return 0;
	}
} 

int build_tk_message_with_message(struct tk_message *tk_msg, message *msg)
{
	int r, len;
	
	memset(tk_msg, 0x00, sizeof(struct tk_message));
	len = MAXMESSAGELEN ;

	r = DSCSERIALIZE_JSON_message(msg, "GBK", tk_msg->body, &len);
	if (r)
		return r;
	else {
		init_tk_message_header(tk_msg, len, MSG_TYPE_COMM_MSG);
		tk_msg->body_len = len;
		tk_msg->body_tmp_len = len;

		return 0;
	}
}

